package ptvv;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Trace extends Thread {
	private BlockingQueue<String> itemsToLog = new LinkedBlockingQueue<String>();
	private ArrayList<String> log = new ArrayList<String>();
	private static final Trace instance = new Trace();
	private static final String SHUTDOWN_REQ = "SHUTDOWN";
	private volatile boolean shuttingDown, loggerTerminated;

	public static Trace getLogger() {
		return instance;
	}

	private Trace() {
		start();
	}

	// Sit in a loop, pulling strings off the queue and logging
	public void run() {
		try {
			String item;
			while ((item = itemsToLog.take()) != SHUTDOWN_REQ) {
				log.add(item);
				System.out.println(item);
			}
		} catch (InterruptedException iex) {
		} finally {
			loggerTerminated = true;
			writeToFile();
		}
	}

	public void log(String str) {
		if (shuttingDown || loggerTerminated)
			return;
		try {
			itemsToLog.put(str);
		} catch (InterruptedException iex) {
			writeToFile();
			Thread.currentThread().interrupt();

			throw new RuntimeException("Unexpected interruption");
		}
	}

	public void writeToFile() {
		System.out.println("writing");
		try {
			// Create file
			FileWriter fstream = new FileWriter("out.txt");
			BufferedWriter out = new BufferedWriter(fstream);
			for (String str : log) {
				out.write(str + "\n");
			}
			// out.write("Hello Java");
			// Close the output stream
			out.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
	}

}